home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / assem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  37.3 KB  |  1,781 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * Harvest C assembler module
  35.  * 
  36.  * 
  37.  */
  38.  
  39.  
  40. #include "conditcomp.h"
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include "structs.h"
  44. #include "as.h"
  45. #include "lookup.h"
  46. #include "regs.h"
  47.  
  48. #pragma segment Assembler
  49.  
  50. struct regs                     iregs[] =
  51. {                /* pre-defined internal register names */
  52. #ifdef M68020
  53.     "CAAR", CREG, CAAR,
  54.     "caar", CREG, CAAR,
  55.     "CACR", CREG, CACR,
  56.     "cacr", CREG, CACR,
  57.     "ISP", CREG, ISP,
  58.     "isp", CREG, ISP,
  59.     "MSP", CREG, MSP,
  60.     "msp", CREG, MSP,
  61. #endif
  62.     "DFC", CREG, DFC,
  63.     "dfc", CREG, DFC,
  64.     "SFC", CREG, SFC,
  65.     "sfc", CREG, SFC,
  66.     "USP", CREG, USP,
  67.     "usp", CREG, USP,
  68.     "VBR", CREG, VBR,
  69.     "vbr", CREG, VBR,
  70.  
  71. /* extended indexed addressing registers */
  72.     "ZA0", ZAREG, 0,
  73.     "za0", ZAREG, 0,
  74.     "ZA1", ZAREG, 1,
  75.     "za1", ZAREG, 1,
  76.     "ZA2", ZAREG, 2,
  77.     "za2", ZAREG, 2,
  78.     "ZA3", ZAREG, 3,
  79.     "za3", ZAREG, 3,
  80.     "ZA4", ZAREG, 4,
  81.     "za4", ZAREG, 4,
  82.     "ZA5", ZAREG, 5,
  83.     "za5", ZAREG, 5,
  84.     "ZA6", ZAREG, 6,
  85.     "za6", ZAREG, 6,
  86.     "ZA7", ZAREG, 7,
  87.     "za7", ZAREG, 7,
  88.     "ZD0", ZDREG, 0,
  89.     "zd0", ZDREG, 0,
  90.     "ZD1", ZDREG, 1,
  91.     "zd1", ZDREG, 1,
  92.     "ZD2", ZDREG, 2,
  93.     "zd2", ZDREG, 2,
  94.     "ZD3", ZDREG, 3,
  95.     "zd3", ZDREG, 3,
  96.     "ZD4", ZDREG, 4,
  97.     "zd4", ZDREG, 4,
  98.     "ZD5", ZDREG, 5,
  99.     "zd5", ZDREG, 5,
  100.     "ZD6", ZDREG, 6,
  101.     "zd6", ZDREG, 6,
  102.     "ZD7", ZDREG, 7,
  103.     "zd7", ZDREG, 7,
  104.     "zpc", ZPC, 0,
  105.     "ZPC", ZPC, 0,
  106.  
  107. #ifdef FLOAT
  108.     "FP0", FREG, 0,
  109.     "fp0", FREG, 0,
  110.     "FP1", FREG, 1,
  111.     "fp1", FREG, 1,
  112.     "FP2", FREG, 2,
  113.     "fp2", FREG, 2,
  114.     "FP3", FREG, 3,
  115.     "fp3", FREG, 3,
  116.     "FP4", FREG, 4,
  117.     "fp4", FREG, 4,
  118.     "FP5", FREG, 5,
  119.     "fp5", FREG, 5,
  120.     "FP6", FREG, 6,
  121.     "fp6", FREG, 6,
  122.     "FP7", FREG, 7,
  123.     "fp7", FREG, 7,
  124.     "FPCR", FCREG, FPCR,
  125.     "fpcr", FCREG, FPCR,
  126.     "FPSR", FCREG, FPSR,
  127.     "fpsr", FCREG, FPSR,
  128.     "FPIAR", FCREG, FPIAR,
  129.     "fpiar", FCREG, FPIAR,
  130. #endif
  131.  
  132. #ifdef PMMU
  133.     "AC", PREG, AC,
  134.     "ac", PREG, AC,
  135.     "BAC0", PREG, BAC0,
  136.     "bac0", PREG, BAC0,
  137.     "BAC1", PREG, BAC1,
  138.     "bac1", PREG, BAC1,
  139.     "BAC2", PREG, BAC2,
  140.     "bac2", PREG, BAC2,
  141.     "BAC3", PREG, BAC3,
  142.     "bac3", PREG, BAC3,
  143.     "BAC4", PREG, BAC4,
  144.     "bac4", PREG, BAC4,
  145.     "BAC5", PREG, BAC5,
  146.     "bac5", PREG, BAC5,
  147.     "BAC6", PREG, BAC6,
  148.     "bac6", PREG, BAC6,
  149.     "BAC7", PREG, BAC7,
  150.     "bac7", PREG, BAC7,
  151.     "BAD0", PREG, BAD0,
  152.     "bad0", PREG, BAD0,
  153.     "BAD1", PREG, BAD1,
  154.     "bad1", PREG, BAD1,
  155.     "BAD2", PREG, BAD2,
  156.     "bad2", PREG, BAD2,
  157.     "BAD3", PREG, BAD3,
  158.     "bad3", PREG, BAD3,
  159.     "BAD4", PREG, BAD4,
  160.     "bad4", PREG, BAD4,
  161.     "BAD5", PREG, BAD5,
  162.     "bad5", PREG, BAD5,
  163.     "BAD6", PREG, BAD6,
  164.     "bad6", PREG, BAD6,
  165.     "BAD7", PREG, BAD7,
  166.     "bad7", PREG, BAD7,
  167.     "CAL", PREG, CAL,
  168.     "cal", PREG, CAL,
  169.     "CRP", PREG, CRP,
  170.     "crp", PREG, CRP,
  171.     "DRP", PREG, DRP,
  172.     "drp", PREG, DRP,
  173.     "PCSR", PREG, PCSR,
  174.     "pcsr", PREG, PCSR,
  175.     "PSR", PREG, PSR,
  176.     "psr", PREG, PSR,
  177.     "SCC", PREG, SCC,
  178.     "scc", PREG, SCC,
  179.     "SRP", PREG, SRP,
  180.     "srp", PREG, SRP,
  181.     "TC", PREG, TC,
  182.     "tc", PREG, TC,
  183.     "VAL", PREG, VAL,
  184.     "val", PREG, VAL,
  185.     "TT0", PREG, TT0,
  186.     "tt0", PREG, TT0,
  187.     "TT1", PREG, TT1,
  188.     "tt1", PREG, TT1,
  189. #endif
  190.  
  191.     "A0", AREG, 0,
  192.     "a0", AREG, 0,
  193.     "A1", AREG, 1,
  194.     "a1", AREG, 1,
  195.     "A2", AREG, 2,
  196.     "a2", AREG, 2,
  197.     "A3", AREG, 3,
  198.     "a3", AREG, 3,
  199.     "A4", AREG, 4,
  200.     "a4", AREG, 4,
  201.     "A5", AREG, 5,
  202.     "a5", AREG, 5,
  203.     "A6", AREG, 6,
  204.     "a6", AREG, 6,
  205.     "A7", AREG, 7,
  206.     "SP", AREG, 7,
  207.     "a7", AREG, 7,
  208.     "sp", AREG, 7,
  209.     "D0", DREG, 0,
  210.     "d0", DREG, 0,
  211.     "D1", DREG, 1,
  212.     "d1", DREG, 1,
  213.     "D2", DREG, 2,
  214.     "d2", DREG, 2,
  215.     "D3", DREG, 3,
  216.     "d3", DREG, 3,
  217.     "D4", DREG, 4,
  218.     "d4", DREG, 4,
  219.     "D5", DREG, 5,
  220.     "d5", DREG, 5,
  221.     "D6", DREG, 6,
  222.     "d6", DREG, 6,
  223.     "D7", DREG, 7,
  224.     "d7", DREG, 7,
  225.     "CCR", SREG, CCR,
  226.     "ccr", SREG, CCR,
  227.     "SR", SREG, SR,
  228.     "sr", SREG, SR,
  229.     "PC", PC, 0,
  230.     "pc", PC, 0,
  231.     NULL, 0, 0
  232. };
  233.  
  234. unsigned char                  *BitsBuffer;
  235. int                             BBIndex;
  236. int                             thesz;    /* bitmap form of Ext                   */
  237. int                             Pass;
  238. int                             Pc = 0;    /* Program Counter                      */
  239. int                             Old_pc = 0;    /* Program Counter at
  240.                          * beginning         */
  241. int                             Fwdsize = W;    /* default fwd ref size                 */
  242.  
  243. void
  244. MPW_Reference(unsigned char FlagsByte, unsigned short RefID, long
  245.           offset, MPWListVia_t Records);
  246.     unsigned short
  247.                                     NameID(MPWDictListVia_t Dicts, char *name, unsigned char FlagsByte, int
  248.                                        isdefined, MPWListVia_t Records);
  249.  
  250.     void                            Gen68Error(char *);
  251.  
  252. /*
  253.  * loword --- return low word of a long
  254.  */
  255.     int
  256.                                     loword(long i)
  257. {
  258.     return (i & 0xFFFF);
  259. }
  260.  
  261. /*
  262.  * hiword --- return high word of a long
  263.  */
  264. int
  265. hiword(long i)
  266. {
  267.     return ((i >> 16) & 0xFFFF);
  268. }
  269.  
  270. /*
  271.  * lobyte --- return low byte of an int
  272.  */
  273. int
  274. lobyte(int i)
  275. {
  276.     return (i & 0xFF);
  277. }
  278.  
  279. /*
  280.  * hibyte --- return high byte of a short int
  281.  */
  282. int
  283. hibyte(int i)
  284. {
  285.     return ((i >> 8) & 0xFF);
  286. }
  287.  
  288. /*
  289.  * reverse --- reverse the bits in an int
  290.  * 
  291.  * Algorithm from Dr. Dobbs Journal #46, June/July 1980, p.48 Original by C.
  292.  * Strachey [CACM 4:3 961 p.146]
  293.  */
  294. int
  295. reverse(int val)
  296. {
  297.     static int                      mask[] =
  298.     {0x55555555, 0x33333333,
  299.      0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
  300.     register int                    i = val;
  301.     register int                    j = 16;
  302.     register int                    k = 4;
  303.  
  304.     while (j) {
  305.     i = ((i & mask[k]) << j) | ((i >> j) & mask[k]);
  306.     j >>= 1;
  307.     k--;
  308.     }
  309.     return (i);
  310. }
  311.  
  312.  
  313. /*
  314.  * emit --- emit a byte to code file
  315.  */
  316. void
  317. emit(unsigned char bt)
  318. {
  319.     Pc++;
  320.     BitsBuffer[BBIndex++] = bt;
  321. }
  322.  
  323.  
  324. /*
  325.  * eword --- emit a word to code file
  326.  */
  327. void
  328. eword(int wd)
  329. {
  330.     emit(hibyte(wd));
  331.     emit(lobyte(wd));
  332. }
  333.  
  334. /*
  335.  * elong --- emit a long to code file
  336.  */
  337. void
  338. elong(long wd)
  339. {
  340.     eword(hiword(wd));
  341.     eword(loword(wd));
  342. }
  343.  
  344. /*
  345.  * mne_lookOP --- mnemonic lookup
  346.  * 
  347.  * Return pointer to an mne structure if found.
  348.  */
  349. struct mne                     *
  350. mne_lookOP(Opcode_t OP)
  351. {
  352.     register struct mne            *low, *high;
  353.     extern struct mne               mnemonic[];
  354.     extern int                      Nmne;
  355.  
  356.     low = &mnemonic[0];
  357.     high = &mnemonic[Nmne - 1];    /* last entry in table is always empty */
  358.     while (low <= high) {
  359.     if (low->OP == OP)
  360.         return low;
  361.     low++;
  362.     }
  363.     return (NULL);
  364. }
  365.  
  366. /*
  367.  * mne_look --- mnemonic lookup
  368.  * 
  369.  * Return pointer to an mne structure if found.
  370.  */
  371. struct mne                     *
  372. mne_look(EString_t str)
  373. {
  374.     register struct mne            *low, *high, *mid;
  375.     int                             cond;
  376.     extern struct mne               mnemonic[];
  377.     extern int                      Nmne;
  378.  
  379.     low = &mnemonic[0];
  380.     high = &mnemonic[Nmne - 1];    /* last entry in table is always empty */
  381.     while (low <= high) {
  382.     mid = low + (high - low) / 2;
  383.     if ((cond = strcmp(Via(str), mid->mne_name)) < 0)
  384.         high = mid - 1;
  385.     else if (cond > 0)
  386.         low = mid + 1;
  387.     else
  388.         return (mid);
  389.     }
  390.     return (NULL);
  391. }
  392.  
  393.  
  394. void
  395. PutEA(LocAMVia_t loc, struct ea * e)
  396. {
  397.     if (!loc)
  398.     return;
  399.     if (!e)
  400.     return;
  401.     e->MPWRef = NULL;
  402.     e->siz = 0;
  403.     e->konst = 0;
  404.     switch (GetLocAM(loc)) {
  405. #ifdef INLINEASM
  406.     case M68am_OtherFormat:
  407.     *e = Via(*(Via(loc)->OtherFormat));
  408.     break;
  409. #endif
  410.     case M68am_DReg:
  411.     e->type = DN;
  412.     e->reg = GetLocDReg(loc);
  413.     break;
  414.     case M68am_ARegDirect:
  415.     e->type = AN;
  416.     e->reg = GetLocAReg(loc);
  417.     break;
  418.     case M68am_ARegIndirect:
  419.     e->type = ANI;
  420.     e->reg = GetLocAReg(loc);
  421.     break;
  422.     case M68am_ARegPostInc:
  423.     e->type = PSTINC;
  424.     e->reg = GetLocAReg(loc);
  425.     break;
  426.     case M68am_ARegPreDec:
  427.     e->type = PREDEC;
  428.     e->reg = GetLocAReg(loc);
  429.     break;
  430.     case M68am_FSANEtemp:
  431.     case M68am_ARegDisplaceFIELD:
  432.     case M68am_ARegDisplace:
  433.     e->type = INDEX;
  434.     e->itype = D16AN;
  435.     e->reg = GetLocAReg(loc);
  436.     e->konst = GetLocConstant(loc);
  437.     e->siz = 2;
  438.     break;
  439.     case M68am_ARegDispIndx:
  440.     /* Not done */
  441.     e->type = EMPTY;
  442.     e->itype = D16AN;
  443.     e->MPWRef = NULL;
  444.     e->reg = GetLocAReg(loc);
  445.     e->konst = 0;
  446.     e->siz = 2;
  447.     break;
  448.     case M68am_AbsShort:
  449.     e->type = EXPR;
  450.     e->konst = GetLocConstant(loc);
  451.     e->siz = 2;
  452.     break;
  453.     case M68am_AbsLong:
  454.     e->type = EXPR;
  455.     e->konst = GetLocConstant(loc);
  456.     e->siz = 4;
  457.     break;
  458.     case M68am_PCLabelDisplace:
  459.     e->type = PCINDEX;
  460.     e->itype = D16AN;
  461.     e->siz = 2;
  462.     if (Via(GetLocLabel(loc))->M68kDef.where)
  463.         e->konst = Via(Via(GetLocLabel(loc))->M68kDef.where)->Address;
  464.     else
  465.         e->konst = 0;
  466.     break;
  467.     case M68am_PCDisplace:
  468.     e->type = PCINDEX;
  469.     e->itype = D16AN;
  470.     e->konst = GetLocConstant(loc);
  471.     e->siz = 2;
  472.     break;
  473.     case M68am_PCDispIndx:
  474.     /* Not done */
  475.     e->type = EMPTY;
  476.     e->itype = D16AN;
  477.     e->MPWRef = NULL;
  478.     e->reg = GetLocAReg(loc);
  479.     e->konst = 0;
  480.     e->siz = 2;
  481.     break;
  482.     case M68am_Immediate:
  483.     e->type = IMMED;
  484.     e->konst = GetLocConstant(loc);
  485.     break;
  486.     case M68am_MultReg* Not done */
  487.     e->type = EMPTY;
  488.     e->itype = D16AN;
  489.     e->MPWRef = NULL;
  490.     e->reg = GetLocAReg(loc);
  491.     e->konst = 0;
  492.     e->siz = 0;
  493.     break;
  494.     case M68am_SR:
  495.     e->type = SR;
  496.     break;
  497.     case M68am_CCR:
  498.     e->type = CCR;
  499.     break;
  500.     case M68am_USP:
  501.     /* Not done */
  502.     e->type = EMPTY;
  503.     e->itype = D16AN;
  504.     e->MPWRef = NULL;
  505.     e->reg = GetLocAReg(loc);
  506.     e->konst = 0;
  507.     e->siz = 0;
  508.     break;
  509.     case M68am_Label:
  510.     e->type = EXPR;
  511.     e->MPWRef = GetLocLabel(loc);
  512.     if (Via(GetLocLabel(loc))->M68kDef.where)
  513.         e->konst = Via(Via(GetLocLabel(loc))->M68kDef.where)->Address;
  514.     else
  515.         e->konst = 0;
  516.     e->siz = 2;
  517.     break;
  518.     case M68am_FReg:
  519.     e->type = FN;
  520.     e->reg = GetLocFReg(loc);
  521.     break;
  522.     case M68am_ARegLabelDisplace:
  523.     e->type = INDEX;
  524.     e->itype = D16AN;    /* Unless we are using 68020 >32k globals */
  525.     e->MPWRef = GetLocLabel(loc);
  526.     e->reg = GetLocAReg(loc);
  527.     e->konst = 0;
  528.     e->siz = 2;
  529.     break;
  530.     case M68am_LargeGlobal:
  531.     e->type = IMMED;
  532.     e->MPWRef = GetLocLabel(loc);
  533.     e->konst = 0;
  534.     e->siz = 2;
  535.     break;
  536.     case M68am_WhatModeIsThis:
  537.     default:
  538.     /* Some sort of error here ? */
  539.     break;
  540.     }
  541. }
  542.  
  543. #define MAXEA   30
  544.  
  545. struct ea                       Eas[MAXEA] =
  546. {0};                /* parsed ea's */
  547. #define sDN     (1<<DN)
  548. #define sAN     (1<<AN)
  549. #define sANI    (1<<ANI)
  550. #define sPREDEC (1<<PREDEC)
  551. #define sPSTINC (1<<PSTINC)
  552. #define sINDEX  (1<<INDEX)
  553. #define sEXPR   (1<<EXPR)
  554. #define sIMMED  (1<<IMMED)
  555. #define sPCINDEX (1<<PCINDEX)
  556. #define sCN     (1<<CN)
  557.  
  558. /*
  559.  * eatab --- bit map of legal modes for composite EA types
  560.  */
  561. int                             eatab[] =
  562. {
  563.     sDN | sAN,            /* Rn */
  564.   sDN | sAN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR | sIMMED | sPCINDEX,    /* anyea */
  565.     sANI | sINDEX | sEXPR | sPCINDEX,    /* control */
  566.     sANI | sPREDEC | sPSTINC | sINDEX | sEXPR,    /* altmem */
  567.     sDN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR,    /* datalt */
  568.     sDN | sAN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR,    /* alter */
  569.     sDN | sANI | sPREDEC | sPSTINC | sINDEX | sEXPR | sIMMED | sPCINDEX,    /* data */
  570.     sANI | sPREDEC | sINDEX | sEXPR,    /-GÄh */
  571.     sANI | sPSTINC | sINDEX | sEXPR | sPCINDEX,    /* ctlpst */
  572.     sANI | sINDEX | sEXPR,    /* ctlalt */
  573.     sANI | sPREDEC | sPSTINC | sINDEX | sEXPR | sIMMED | sPCINDEX,    /* memory */
  574.     sDN | sEXPR | sCN,        /* PEA1  */
  575.     0                /* multi */
  576. };
  577.  
  578. /*
  579.  * eamatch --- match a general ea class against the specific operand
  580.  * 
  581.  * gen is taken from the template, and spec comes from the type field of the
  582.  * scanned ea.  Gen classes less than RN are basic types, classes RN and
  583.  * above are composite types.  This routine will break if there are more
  584.  * basic types than bits in an int.
  585.  */
  586. int
  587. eamatch(int gen, int spec)
  588. {
  589.     if (gen < RN)
  590.     return (gen == spec);
  591.     return (eatab[gen - RN] & (1 << spec));
  592. }
  593.  
  594. /*
  595.  * tmpl_match --- match size and operands of instruction
  596.  * 
  597.  * Given a pointer to N entries in the template table, scan and try to match the
  598.  * operand field of the line with one of them.  Return NULL if nothing
  599.  * matches, otherwise a pointer to the matching entry.
  600.  * 
  601.  * A successful match will leave the processed operands in the Eas array.  The
  602.  * first unused entry in Eas will have a type of EMPTY.
  603.  * 
  604.  * To be a successful match, the template must first match the size field. After
  605.  * this, if the type is EMPTY the match is successful.  Also, if the type is
  606.  * MULTI, an open ended number of EXPR's will be scanned.
  607.  */
  608. struct tmpl                    *
  609. tmpl_match(struct tmpl * p, int n, InstVia_t inst)
  610. {
  611.     register struct ea             *e = Eas;
  612.  
  613.     Eas[0].type = Eas[1].type = Eas[2].type = Eas[3].type = EMPTY;
  614.  
  615.     PutEA(Via(inst)->left, e++);
  616.     PutEA(Via(inst)->right, e++);
  617.  
  618.     /* 1-4 ea's now in Eas */
  619.  
  620.     while (n--) {
  621.     if ((thesz & p->sizes) &&
  622.         eamatch(p->modes[0], Eas[0].type) &&
  623.         eamatch(p->modes[1], Eas[1].type) &&
  624.         eamatch(p->modes[2], Eas[2].type) &&
  625.         eamatch(p->modes[3], Eas[3].type))
  626.         return (p);
  627.     p++;
  628.     }
  629.     return (NULL);
  630. }
  631.  
  632.  
  633. #define    cpid(x)    ((x)<<9)    /* coprocessor id field */
  634.  
  635. #ifdef PMMU
  636. int                             Ppid = cpid(0);    /* PMMU coprocessor ID */†≈hU
  637.  
  638. #ifdef FLOAT
  639.  
  640. int                             Fpid = cpid(1);    /* floating point coprocessor
  641.                          * ID */
  642. int                             o_fpid(), o_round(), o_prec();
  643.  
  644. #endif
  645.  
  646. /* range checking categories */
  647. #define UBYTE   0        /* unsigned byte */
  648. #define SBYTE   1        /* signed byte */
  649. #define XBYTE   2        /* extended byte */
  650. #define UWORD   3        /* unsigned word */
  651. #define SWORD   4        /* signed word */
  652. #define XWORD   5        /* extended word */
  653. #define QUK     6        /* quick value 1-8 */
  654. #define LOW3    7        /* 3 bit field */
  655. #define LOW4    8        /* 4 */
  656. #define LOW5    9        /* 5 */
  657. #define    LOW6    10        /* 6 */
  658. #define LOW7    11        /* 7 */
  659. #define LOW7S   12        /* 7, signed */
  660.  
  661. struct ranges {
  662.     int                             r_min;    /* minimum value allowed */
  663.     int                             r_max;    /* max. allowed */
  664.     int                             r_mask;    /* return value mask */
  665. };
  666.  
  667. struct ranges                   ckrange[] =
  668. {
  669.     0, MAXUBYTE, 0x00FF,
  670.     MINBYTE, MAXBYTE, 0x00FF,
  671.     MINBYTE, MAXUBYTE, 0x00FF,
  672.     0, MAXUWORD, 0xFFFF,
  673.     MINWORD, MAXWORD, 0xFFFF,
  674.     MINWORD, MAXUWORD, 0xFFFF,
  675.     1, 8, 0x0007,
  676.     0, 7, 0x0007,
  677.     0, 15, 0x000F,
  678.     0, 31, 0x001F,
  679.     0, 63, 0x003F,
  680.     0, 127, 0x007F,
  681.     -64, 63, 0x007F,
  682. };
  683.  
  684. /*
  685.  * fsizchk --- check that size of instruction matches src/dst
  686.  */
  687. void
  688. fsizchk(struct ea * e)
  689. {
  690.     if ((thesz & (D | X | P)) && e->type == DN)
  691.     Gen68Error("Bad size");
  692. }
  693.  
  694. /*
  695.  * check --- verify that constant is within bounds
  696.  */
  697. int
  698. check(int konst, int type)
  699. {
  700.     int                             lo, hi;
  701.  
  702.     lo = ckrange[type].r_min;
  703.     hi = ckrange[type].r_max;
  704.     if (konst < lo || konst > hi) {
  705.     /* TODO Generate a warning */
  706.     }
  707.     return (konst & ckrange[type].r_mask);
  708. }
  709.  
  710. /*
  711.  * size76 --- compute opcode bits 7 and 6 from thesz specifier
  712.  */
  713. int
  714. size76(void)
  715. {
  716.     int                             s = 0;
  717.  
  718.     switch (thesz) {
  719.     case B:
  720.     s = 0x00;
  721.     break;
  722.     case W:
  723.     case U:
  724.     s = 0x40;
  725.     break;
  726.     case L:
  727.     s = 0x80;
  728.     break;
  729.     default:
  730.     Gen68Error("Bad size in size76");
  731.  åDç return (s);
  732. }
  733.  
  734. /*
  735.  * size109 --- compute opcode bits 10 and 9 from size specifier
  736.  */
  737. int
  738. size109(void)
  739. {
  740.     int                             s = 0;
  741.  
  742.     switch (thesz) {
  743.     case B:
  744.     s = 0x000;
  745.     break;
  746.     case W:
  747.     case U:
  748.     s = 0x200;
  749.     break;
  750.     case L:
  751.     s = 0x400;
  752.     break;
  753.     default:
  754.     Gen68Error("Bad size in size109");
  755.     }
  756.     return (s);
  757. }
  758.  
  759. /*
  760.  * size109b --- compute opcode bits 10 and 9 from size specifier (alternate)
  761.  */
  762. int
  763. size109b(void)
  764. {
  765.     int                             s = 0;
  766.  
  767.     switch (thesz) {
  768.     case B:
  769.     s = 0x200;
  770.     break;
  771.     case W:
  772.     case U:
  773.     s = 0x400;
  774.     break;
  775.     case L:
  776.     s = 0x600;
  777.     break;
  778.     default:
  779.     Gen68Error("Bad size in size109b");
  780.     }
  781.     return (s);
  782. }
  783.  
  784. /*
  785.  * adreg --- return 4 bit encoding for An or Dn (shift left by 12)
  786.  */
  787. int
  788. adreg(struct ea * e)
  789. {
  790.     int                             r = e->reg;
  791.  
  792.     if (e->type == AN)
  793.     r += 8;
  794.     return (r << 12);
  795. }
  796.  
  797. /*
  798.  * modreg --- generate mode/register field from ea structure
  799.  * 
  800.  * return is a 6-bit field suitable for adding to a base opcode.
  801.  */
  802. int
  803. modreg(struct ea * e)
  804. {
  805.     register int                    mr = 0;
  806.  
  807.     switch (e->type) {
  808.     case DN:
  809.     mr = 000 + e->reg;
  810.     break;
  811.     case AN:
  812.     mr = 010 + e->reg;
  813.     break;
  814.     case ANI:
  815.     mr = 020 + e->reg;
  816.     break;
  817.     case PSTINC:
  818.     mr = 030 + e->reg;
  819.     break;
  820.     case PREDEC:
  821.     mr = 040 + e->reg;
  822.     break;
  823.     case INDEX:
  824.     mr = e->itype == D16AN ? 050 + e->reg : 060 + e->reg;
  825.     break;
  826.     case IMMED:
  827.     mr = 074;
  828.     break;
  829.     case EXPR:
  830.     mr = e->siz == L ? 071 : 070;
  831.     break;
  832.     case PCINDEX:
  833.     mr = e->itype == D16AN ? 072 : 073;
  834.     break;
  835.     default:
  836.     Gen68Error("Bad type in modreg");
  837.     }
  838.     return (mr);
  839. }
  840.  
  841. /*
  842.  * genxreg --- generate index register spec for indexed postword
  843.  */
  844. int
  845. genxreg(struct ea * e)
  846. {
  847.     int                             wrd;
  848.  
  849.     wrd = e->stat2 ? 0x8000 : 0x0000;
  850.     wrd += e->reg2 << 12;
  851.     if (e->siz == L)
  852.     wrd += (1 << 11);
  853.     wrd += e->scl << 9;
  854.     return (wrd);
  855. }
  856.  
  857. /*
  858.  * finish --- generate post-words for an instruction
  859.  */
  860. void
  861. finish(struct ea ˇä„   if (e->MPWRef && Pass == 2) {
  862.     int                             id;
  863. #ifdef OLDMEM
  864.     HLock((Handle) e->MPWRef);
  865. #endif
  866.     id = NameID(OBJNameList, Via(e->MPWRef)->name, 0, 0, GlobalRecords);
  867. #ifdef OLDMEM
  868.     HUnlock((Handle) e->MPWRef);
  869. #endif
  870.     MPW_Reference(128 + 16, id, Pc, GlobalRecords);
  871.     }
  872.     switch (e->type) {
  873.     case DN:
  874.     case AN:
  875.     case ANI:
  876.     case PSTINC:
  877.     case PREDEC:
  878.     break;
  879.     case PCINDEX:
  880.     e->konst -= Pc;
  881.     case INDEX:
  882.     switch (e->itype) {
  883.     case D16AN:
  884.         eword(check(e->konst, SWORD));
  885.         break;
  886.     case BRIEF:
  887.         eword(genxreg(e) + check(e->konst, SBYTE));
  888.         break;
  889.     case FULL:
  890.         if (e->xn_sup && e->prepst)    /* reserved combination */
  891.         e->prepst = 0;
  892.         eword(genxreg(e) + 0x100 + (e->br_sup << 7) +
  893.           (e->xn_sup << 6) + (e->bdsiz << 4) +
  894.           (e->prepst << 2) + e->odsiz);
  895.         switch (e->bdsiz) {
  896.         case 1:
  897.         break;        /* supressed */
  898.         case 2:
  899.         eword(check(e->konst, SWORD));
  900.         break;
  901.         case 3:
  902.         elong(e->konst);
  903.         break;
  904.         default:
  905.         Gen68Error("finish1");
  906.         }
  907.         switch (e->odsiz) {
  908.         case 0:        /* to allow An indirect w/ index */
  909.         case 1:
  910.         break;        /* supressed */
  911.         case 2:
  912.         eword(check(e->const2, SWORD));
  913.         break;
  914.         case 3:
  915.         elong(e->const2);
  916.         break;
  917.         default:
  918.         Gen68Error("finish2");
  919.         }
  920.         break;
  921.     default:
  922.         Gen68Error("finish3");
  923.     }
  924.     break;
  925.     case IMMED:
  926.     if (thesz == L)
  927.         elong(e->konst);
  928.     else
  929.         eword(e->konst);    /* note: no range check here */
  930.     break;
  931.     case EXPR:
  932.     if (e->siz == L)
  933.         elong(e->konst);
  934.     else
  935.         eword(check(e->konst, SWORD));
  936.     break;
  937.     default:
  938.     Gen68Error("finish4");
  939.     }
  940. }
  941.  
  942. /*
  943.  * fsize --- return encoded size for floating point ea
  944.  */
  945. int
  946. fsize(void)
  947. {
  948.     int                             sz = 0;
  949.  
  950.     switch (thesz) {
  951.     case L:
  952.     sz = 0x0000;
  953.     break;
  954.     case S:
  955.     sz = 0x0400;
  956.     break;
  957.     case X:
  958.     sz = 0x0800;
  959.     break;
  960.     case P:
  961.     sz = 0x0C00;
  962.     break;
  963.     case W:
  964.     sz = 0x1000;
  965.     break;
  966.     case D:
  967.     sz = 0x1400;
  968.     break;
  969.     case B:
  970.     sz = 0x1800;
  971.     break;
  972.     /* case P: sz = 0x1C00; break;    ~zñzd? */
  973.     default:
  974.     Gen68Error("Bad size in fsize");
  975.     }
  976.     return (sz);
  977. }
  978.  
  979. /*
  980.  * checkfclist --- look for invalid fclist combinations
  981.  * 
  982.  * Dn addressing allowed on ea only if there is a single register in the list.
  983.  * An addressing is allowed only if the single register FPIAR is specified.
  984.  */
  985. void
  986. checkfclist(int r, struct ea * e)
  987. {                /* r is a register list */
  988.     if (e->type == AN && (r & (FPCR | FPSR)))
  989.     Gen68Error("An addressing allowed only on FPIAR");
  990.     else if (e->type == DN) {
  991.     if (r != FPCR && r != FPSR && r != FPIAR)
  992.         Gen68Error("Only a single FP ctrl. reg may be selected");
  993.     }
  994. }
  995.  
  996. /*
  997.  * getrlist --- return register list mask for an EA
  998.  */
  999. int
  1000. getrlist(struct ea * e)
  1001. {
  1002.     int                             rlist = 0;
  1003.  
  1004.     switch (e->type) {
  1005.     case AN:
  1006.     rlist = 1 << (e->reg + 8);
  1007.     break;
  1008.     case DN:
  1009.     rlist = 1 << e->reg;
  1010.     break;
  1011.     case RLIST:
  1012.     rlist = e->reg;
  1013.     break;
  1014.     default:
  1015.     Gen68Error("getrlist");
  1016.     }
  1017.     return (rlist);
  1018. }
  1019.  
  1020. /*
  1021.  * bitfld --- return bit field extension word
  1022.  */
  1023. int
  1024. bitfld(struct ea * e, int r)
  1025. {
  1026.     int                             offset, width;
  1027.  
  1028.     if (e->type != FIELD)
  1029.     Gen68Error("Botch in bitfld");
  1030.  
  1031.     if (e->stat)
  1032.     offset = check(e->konst, LOW5);
  1033.     else
  1034.     offset = e->reg + 0x20;
  1035.  
  1036.     if (e->stat2)
  1037.     width = check(e->const2, LOW5);
  1038.     else
  1039.     width = e->reg2 + 0x20;
  1040.  
  1041.     return ((r << 12) + (offset << 6) + width);
  1042. }
  1043.  
  1044. /*
  1045.  * do_op --- process mnemonic
  1046.  */
  1047. void
  1048. do_op(int opclass, int op, int op2)
  1049. {
  1050.     extern struct ea                Eas[];
  1051.     register struct ea             *ea1 = &Eas[0];
  1052.     register struct ea             *ea2 = &Eas[1];
  1053.     register struct ea             *ea3 = &Eas[2];
  1054.     register int                    tmp;
  1055.     register int                    dist;    /* distance on branches */
  1056.     register int                    rlist;    /* bit map of register list */
  1057.  
  1058.     switch (opclass) {
  1059.     case INH:            /* inherent */
  1060.     eword(op);
  1061.     break;
  1062.  
  1063.     case RXRY:            /* Rx and Ry, no size */
  1064.     eword(op + (ea2->reg << 9) + ea1->reg);
  1065.     break;
  1066.  
  1067.     case RXRYS:    xKü7nd Ry, sized */
  1068.     eword(op + (ea2->reg << 9) + size76() + ea1->reg);
  1069.     break;
  1070.  
  1071.     case RXRYR:        /* Rx and Ry, reversed */
  1072.     eword(op + (ea1->reg << 9) + ea2->reg);
  1073.     break;
  1074.  
  1075.     case RXRYP:        /* Rx and Ry, pack/unpack */
  1076.     eword(op + (ea2->reg << 9) + ea1->reg);
  1077.     eword(check(ea3->konst, UWORD));
  1078.     break;
  1079.  
  1080.     case EAREG:        /* ea to register */
  1081.     eword(op + (ea2->reg << 9) + modreg(ea1));
  1082.     finish(ea1);
  1083.     break;
  1084.  
  1085.     case EAREGS:        /* ea to register, sized */
  1086.     eword(op + (ea2->reg << 9) + size76() + modreg(ea1));
  1087.     finish(ea1);
  1088.     break;
  1089.  
  1090.     case REGEA:        /* register to ea */
  1091.     eword(op + (ea1->reg << 9) + modreg(ea2));
  1092.     finish(ea2);
  1093.     break;
  1094.  
  1095.     case REGEAS:        /* register to ea, signed */
  1096.     eword(op + (ea1->reg << 9) + size76() + modreg(ea2));
  1097.     finish(ea2);
  1098.     break;
  1099.  
  1100.     case IMMEAS:        /* immediate to ea, sized */
  1101.     eword(op + size76() + modreg(ea2));
  1102.     if (thesz == L)
  1103.         elong(ea1->konst);
  1104.     else
  1105.         eword(ea1->konst);
  1106.     finish(ea2);
  1107.     break;
  1108.  
  1109.     case QUKEA:        /* quick immediate to ea */
  1110.     if ((thesz & B) && ea2->type == AN)
  1111.         Gen68Error("Byte not allowed to address reg.");
  1112.     eword(op + (check(ea1->konst, QUK) << 9) + size76() + modreg(ea2));
  1113.     finish(ea2);
  1114.     break;
  1115.  
  1116.     case IMMB:            /* immediate byte */
  1117.     eword(op);
  1118.     eword(check(ea1->konst, UBYTE));
  1119.     break;
  1120.  
  1121.     case IMMW:            /* immediate word */
  1122.     eword(op);
  1123.     eword(check(ea1->konst, XWORD));
  1124.     break;
  1125.  
  1126.     case IMMWS:        /* immediate word, signed */
  1127.     eword(op);
  1128.     eword(check(ea1->konst, SWORD));
  1129.     break;
  1130.  
  1131.     case IMM3:            /* immediate value, 3 bits */
  1132.     eword(op + check(ea1->konst, LOW3));
  1133.     break;
  1134.  
  1135.     case IMM4:            /* immediate value, 4 bits */
  1136.     eword(op + check(ea1->konst, LOW4));
  1137.     break;
  1138.  
  1139.     case RSHIFT:        /* register shift */
  1140.     eword(op + (ea1->reg << 9) + size76() + ea2->reg);
  1141.     break;
  1142.  
  1143.     case QSHIFT:        /* immediate (quick fmt) shift */
  1144.     eword(op + (check(ea1->konst, QUK) << 9) + size76() + ea2->reg);
  1145.     break;
  1146.  
  1147.     case EA:            /* ea */
  1148.     eword(op + modreg(ea1));
  1149.     finish(ea1);
  1150.     break;
  1151.  
  1152.     case EAREV:        /* ea, reversed */
  1153.     eword(op + modreg(ea2));
  1154.     finish(ea2);
  1155.     break;
  1156.  
  1157.     case EAS:            ‚cz•ized */
  1158.     eword(op + size76() + modreg(ea1));
  1159.     finish(ea1);
  1160.     break;
  1161.  
  1162.     case BCC:            /* conditional branches */
  1163.     dist = ea1->konst - (Pc + 2);    /* TODO See if word and long branches
  1164.                      * work */
  1165. #ifdef UNDEFINED
  1166.     if (thesz == U && ea1->force)
  1167.         thesz = Fwdsize;
  1168.     if (thesz == U) {
  1169.         if (dist < MINWORD || dist > MAXWORD)
  1170.         thesz = L;
  1171.         else if (dist < MINBYTE || dist > MAXBYTE)
  1172.         thesz = W;
  1173.         else
  1174.         thesz = B;
  1175.     }
  1176. #else
  1177.     thesz = W;
  1178. #endif
  1179.     switch (thesz) {
  1180.     case B:
  1181.         if (dist == 0 || dist == -1)
  1182.         Gen68Error("Bad branch destination");
  1183.         eword(op + check(dist, SBYTE));
  1184.         break;
  1185.     case W:
  1186.         if (dist == 0 || dist == -1)
  1187.         Gen68Error("Bad branch destination");
  1188.         eword(op);
  1189.         eword(check(dist, SWORD));
  1190.         break;
  1191.     case L:
  1192.         eword(op + 0xFF);
  1193.         elong(dist);
  1194.         break;
  1195.     }
  1196.     break;
  1197.  
  1198.     case BIT:            /* single bit manipulation */
  1199.     eword(op + modreg(ea2));
  1200.     eword(check(ea1->konst, LOW5));
  1201.     finish(ea2);
  1202.     break;
  1203.  
  1204.     case BITFLD:        /* bit fields */
  1205.     eword(op + modreg(ea1));
  1206.     eword(bitfld(ea2, 0));    /* {Dn/#:Dn/#} formatted word */
  1207.     finish(ea1);
  1208.     break;
  1209.  
  1210.     case BITFLD2:        /* bit fields, second format */
  1211.     if (ea2->type == FIELD) {
  1212.         eword(op + modreg(ea1));
  1213.         eword(bitfld(ea2, ea3->reg));    /* {Dn/#:Dn/#} formatted word */
  1214.         finish(ea1);
  1215.     } else {        /* bfins is backwards */
  1216.         eword(op + modreg(ea2));
  1217.         eword(bitfld(ea3, ea1->reg));    /* {Dn/#:Dn/#} formatted word */
  1218.         finish(ea2);
  1219.     }
  1220.     break;
  1221.  
  1222.     case CALLM:        /* callm */
  1223.     eword(op + modreg(ea2));
  1224.     eword(check(ea1->konst, UBYTE));
  1225.     finish(ea2);
  1226.     break;
  1227.  
  1228.     case CAS:            /* cas */
  1229.     eword(op + size109b() + modreg(ea3));
  1230.     eword((ea2->reg << 6) + ea1->reg);
  1231.     finish(ea3);
  1232.     break;
  1233.  
  1234.     case CAS2:            /* cas2 */
  1235.     eword(op + size109b());
  1236.     if (ea3->stat)
  1237.         ea3->reg += 8;
  1238.     eword((ea3->reg << 12) + (ea2->reg << 6) + ea1->reg);
  1239.     if (ea3->stat2)
  1240.         ea3->reg2 += 8;
  1241.     eword((ea3->reg2 << 12) + (ea2->reg2 << 6) + ea1->reg2);
  1242.     break;
  1243.  
  1244.     case CHK:            /* chk */
  1245.     if (thesz != L)
  1246.         op |= 0x0080;
  1247.     eword(op + (ea2->reg << 9) + modreg(ea1));
  1248.     fR: 1);
  1249.     break;
  1250.  
  1251.     case CHK2:            /* chk2,cmp2 */
  1252.     eword(op + size109() + modreg(ea1));
  1253.     eword(op2 + adreg(ea2));
  1254.     finish(ea1);
  1255.     break;
  1256.  
  1257.     case DBCC:            /* dbcc */
  1258.     dist = ea2->konst - (Old_pc + 2);
  1259.     eword(op + ea1->reg);
  1260.     eword(check(dist, SWORD));
  1261.     break;
  1262.  
  1263.     case MULDIV:        /* multiplies and di\edes */
  1264.     eword(fp + modJ.g(ea1));
  1265.     if (…a2->typ@== DN)
  1266.         ea2Ω>reg2 = ea2->reg;
  1267.     eword(op2 + mea2->reg2 <<!129 + ea2->reg);
  1268.     finish(ea1);
  1269.     break;
  1270.  
  1271.     case REG:            /* registêr */
  1272. kword(op + ea1->r}g);
  1273.     €Ueak;
  1274.  
  1275.     case MíVEU:    VÎ* move to/from US@ */
  1276. 9ıf (ea1->type == CN) {
  1277.         if (ea1->reú !- USP)˛        Gen68Error("USP Required");
  1278.         eword(op + ea2->reg);
  1279.     } else {
  1280.         if (ea2-¶reg !„∑USP)
  1281.         Gen68Erro?("USPt¨equired");
  1282.         erord(® + ea1->reg);
  1283.     }
  1284.     break;
  1285.  
  1286.     case REGIMM:        /* register with immediate */
  1287.     eword(op + ea1->reg);
  1288.     if (thesz ==At)
  1289.         elong(eÒ2->kons’‘;
  1290.     else
  1291.         e?ord(ea2->konst);
  1292.     break;
  1293.  
  1294.     cRe MOVE:            /* moe */
  1295.     tmp = modreg(ea2);
  1296.     tmp =¬((tmp & 7) << 3‹ + ((tmp >> 3) & 7);    /* reverse modreg */
  1297.     eword(op + (tmp << ∂) + modreg(ea1));
  1298.     finish(ea1);
  1299.     finish(ea2);
  1300.     ‚reak;
  1301.  
  1302.     case MOVEC:        .* movec */
  1303.     eword(op);
  1304.     if (ea1->type == CN)
  1305.      ;  eword(adreg(ea2) + ea5->reg);
  1306.     else
  1307.         eword(adreg(ea1) + ea2->reg);
  1308.     break;
  1309.  
  1310.     case MOVEQ:        /* move qui¯k */
  1311.     eword(op + (ea2->wg << 9) + check(ea1->konst, SBYTE));
  1312.     break;
  1313.  
  1314.     case MOVEMO:        /* movem register to#@emory */
  1315.     if (ea1->type == IMMED)
  1316.         rlist =ï a1->konst;
  1317.     else
  1318.         j‘ist = getrlist(ea1);
  1319.     if (ea2->type == PREDEC)
  1320.         rlist = reverse(rlist) >> 16;    /* assumes int=32bits */
  1321.     ewnd(op + modreg(ea2));
  1322.     eword(rlist);
  1323.     finish(eaœQ;
  1324.     break;
  1325.  
  1326.     case MONfMI:        /* movem memory to register */
  1327.     if (ea2->type == IMMED)
  1328.         rlist = ea2->konst;
  1329.     else
  1330.         rlist = getrl|{t(ea2);
  1331.     /* prSdec not possible here */
  1332.     ewordôp + modreg(ea1+);
  1333.     ewoyk(rlist);
  1334.     finiÛ¯(ea1);
  1335.     break;
  1336.  
  1337.     case MOVEPO"        /* movep olt ./
  1338.     if (ea2->itype != D16AN)
  1339.         Gen68Error("Simple indexing oŒly");Meword(op + (ea1->reg << 9) + ea2->reg);    ** NOTodreg(ea2) */
  1340.     fhnish(ÃÒ2);
  1341.     b
  1342. mÛ1   case MOVEPI:        /* moveCCin */
  1343.     if (ea1Ì>itype != D16AN)
  1344.         Gen68Error("Simple indexing only");
  1345.     eword(op + (ea2->reg << 9) + ea1->reg);    /* NOT modreg(ea1) */
  1346.     finish(ea1);
  1347.     break;
  1348.  
  1349.     case MOVES:        /* moves */
  1350.     op += size76();
  1351.     if (ea1->type == DN || ea1->type == AN) {
  1352.         eword(op + modreg(ea2));
  1353.         eword(op2 + adreg(ea1));
  1354.         finish(ea2);
  1355.     } else {
  1356.         eword(op + modreg(ea1));
  1357.         eword(op2 + adreg(ea2));
  1358.         finish(ea1);
  1359.     }
  1360.     break;
  1361.  
  1362.     case TRAPCC:        /* trapcc */
  1363.     eword(op + (thesz == W ? 2 : 3));
  1364.     if (thesz == L)
  1365.         elong(ea1->konst);
  1366.     else
  1367.         eword(check(ea1->konst, UWORD));
  1368.     break;
  1369.  
  1370. #ifdef FLOAT
  1371.     case FINH:            /* floating inherent */
  1372.     eword(op + Fpid);
  1373.     eword(op2);
  1374.     break;
  1375.  
  1376.     case FEAREG:        /* floating ea to regiser */
  1377.     fsizchk(ea1);
  1378.     eword(op + Fpid + modreg(ea1));
  1379.     eword(op2 + fsize() + (ea2->reg << 7));
  1380.     finish(ea1);
  1381.     break;
  1382.  
  1383.     case FREGREG:        /* floating register to register */
  1384.     eword(op + Fpid);
  1385.     eword(op2 + (ea1->reg << 10) + (ea2->reg << 7));
  1386.     break;
  1387.  
  1388.     case FMONAD:        /* floating register (monadic) */
  1389.     eword(op + Fpid);
  1390.     eword(op2 + (ea1->reg << 10) + (ea1->reg << 7));
  1391.     break;
  1392.  
  1393.     case FBCC:            /* floating branch */
  1394.     eword(op + Fpid + (thesz == L ? 0x40 : 0));
  1395.     dist = ea1->konst - Pc;
  1396.     if (thesz == L)
  1397.         elong(dist);
  1398.     else
  1399.         eword(check(dist, SWORD));
  1400.     break;
  1401.  
  1402.     case FDBCC:        /* floating dbcc */
  1403.     eword(op + Fpid + ea1->reg);
  1404.     eword(op2);
  1405.     dist = ea2->konst - Pc;
  1406.     eword(check(dist, SWORD));
  1407.     break;
  1408.  
  1409.     case FEA:            /* floating ea */
  1410.     eword(op + Fpid + modreg(ea1));
  1411.     finish(ea1);
  1412.     break;
  1413.  
  1414.     case FSCC:            /* floating scc */
  1415.     eword(op + Fpid + modreg(ea1));
  1416.     eword(op2);
  1417.     finish(ea1);
  1418.     break;
  1419.  
  1420.     case FEAPAIR:        /* floating ea to floating reg pair */
  1421.     fsizchk(ea1);
  1422.     eword(op + Fpid + modreg(ea1));
  1423.     eword(op2 + fsize() + (ea2->reg << 7) + ea2->reg2);
  1424.     finish(ea1);
  1425.     break;
  1426.  
  1427.     case FREGPAIR:        /* floating register to floating reg pair */
  1428.     eword(op + Fpid);
  1429.     eword(op2 + (ea1->reg << 10) + (ea2->reg << 7) + ea2->reg2);
  1430.     break;
  1431.  
  1432.     case FTSTEA:        /* floating test of ea */
  1433.     fQ3a1);
  1434.     eword(op + Fpid + modreg(ea1));
  1435.     eword(op2 + fsize());
  1436.     finish(ea1);
  1437.     break;
  1438.  
  1439.     case FTSTREG:        /* floating test of register */
  1440.     eword(op + Fpid);
  1441.     eword(op2 + (ea1->reg << 10));
  1442.     break;
  1443.  
  1444.     case FMOVE:        /* floating move */
  1445.     fsizchk(ea2);
  1446.     eword(op + Fpid + modreg(ea2));
  1447.     if (ea3->type == EMPTY)
  1448.         eword(op2 + fsize() + (ea1->reg << 7));
  1449.     else if (ea3->type == DYNK)
  1450.         eword(op2 + (ea1->reg << 7) + (ea3->reg << 3));
  1451.     else if (ea3->type == STATK)
  1452.         eword(op2 + (ea1->reg << 7) + check(ea3->konst, LOW7S));
  1453.     else
  1454.         Gen68Error("Botch in FMOVE");
  1455.     finish(ea2);
  1456.     break;
  1457.  
  1458.     case FMOVECR:        /* floating move constant rom */
  1459.     eword(op + Fpid);
  1460.     eword(op2 + (ea2->reg << 7) + check(ea1->konst, LOW7));
  1461.     break;
  1462.  
  1463.     case FMOVEMI:        /* floating move memory to registers */
  1464.     /* predec not possible */
  1465.     eword(op + Fpid + modreg(ea1));
  1466.     if (ea2->type == DN)
  1467.         ea2->reg <<= 4;
  1468.     eword(op2 + ea2->reg);
  1469.     finish(ea1);
  1470.     break;
  1471.  
  1472.     case FMOVEMO:        /* floating move registers to memory */
  1473.     if (ea2->type != PREDEC)
  1474.         op2 += 0x1000;
  1475.     if (ea1->type == FLIST && ea2->type == PREDEC)
  1476.         ea1->reg = (reverse(ea1->reg) >> 24) & 0xFF;
  1477.     if (ea1->type == DN)
  1478.         ea1->reg <<= 4;
  1479.     eword(op + Fpid + modreg(ea2));
  1480.     eword(op2 + ea1->reg);
  1481.     finish(ea2);
  1482.     break;
  1483.  
  1484.     case FMOVEMCI:        /* floating move memory to control regs */
  1485.     checkfclist(ea2->reg, ea1);
  1486.     eword(op + Fpid + modreg(ea1));
  1487.     eword(op2 + ea2->reg);
  1488.     finish(ea1);
  1489.     break;
  1490.  
  1491.     case FMOVEMCO:        /* floating move control regs to memory */
  1492.     checkfclist(ea1->reg, ea2);
  1493.     eword(op + Fpid + modreg(ea2));
  1494.     eword(op2 + ea1->reg);
  1495.     finish(ea2);
  1496.     break;
  1497.  
  1498.     case FTRAPCC:        /* floating trap on condition */
  1499.     eword(op + Fpid + (thesz == W ? 2 : 3));
  1500.     eword(op2);
  1501.     if (thesz == L)
  1502.         elong(ea1->konst);
  1503.     else
  1504.         eword(check(ea1->konst, UWORD));
  1505.     break;
  1506.  
  1507. #endif
  1508.  
  1509. #ifdef PMMU
  1510.     case PINH:            /* PMMU inherent */
  1511.     eword(op + Ppid);
  1512.     eword(op2);
  1513.     break;
  1514.  
  1515.     case PBCC:            /* PMMU branch */
  1516.     eword(op + Ppid + (thesz == L ? 0x40 : 0));
  1517.     dist = ea1->konst - Pc;
  1518.     if (thesz == L)
  1519.         elong(distıfi¶
  1520.         eword(check(dist, SWORD));
  1521.     break;
  1522.  
  1523.     case PDBCC:        /* PMMU dbcc */
  1524.     eword(op + Ppid + ea1->reg);
  1525.     eword(op2);
  1526.     dist = ea2->konst - Pc;
  1527.     eword(check(dist, SWORD));
  1528.     break;
  1529.  
  1530.     case PFLUSH:        /* PFLUSH, PFLUSHG */
  1531.     if (ea3->type != EMPTY)
  1532.         op += modreg(ea3);
  1533.     eword(op + Ppid);
  1534.     eword(op2 + (check(ea2->konst, LOW4) << 5) + pmmu_fc(ea1));
  1535.     if (ea3->type != EMPTY)
  1536.         finish(ea3);
  1537.     break;
  1538.  
  1539.     case PEA:            /* PMMU with single EA */
  1540.     eword(op + Ppid + modreg(ea1));
  1541.     finish(ea1);
  1542.     break;
  1543.  
  1544.     case PLOAD:        /* PMMU load ATC entry */
  1545.     eword(op + Ppid + modreg(ea2));
  1546.     eword(op2 + pmmu_fc(ea1));
  1547.     finish(ea2);
  1548.     break;
  1549.  
  1550.     case PMOVEIF:        /* pmove, with no flush of ATC */
  1551.     switch (ea2->reg) {
  1552.     case SRP:
  1553.     case CRP:
  1554.     case TT0:
  1555.     case TT1:
  1556.     case TC:
  1557.         break;
  1558.     default:
  1559.         Gen68Error("Illegal register for pmovef");
  1560.     }
  1561.     /* FALL THROUGH */
  1562.  
  1563.     case PMOVEI:        /* PMMU load control reg */
  1564.     switch (ea2->reg) {
  1565.     case CRP:
  1566.     case SRP:
  1567.     case DRP:
  1568.         if (ea2->type == DN)
  1569.         Gen68Error("Reg. size mismatch");
  1570.         break;
  1571.     case PCSR:
  1572.         Gen68Error("Read only register");
  1573.         break;
  1574.     }
  1575.     eword(op + Ppid + modreg(ea1));
  1576.     eword(op2 + ea2->reg);
  1577.     finish(ea1);
  1578.     break;
  1579.  
  1580.     case PMOVEO:        /* PMMU store control reg */
  1581.     switch (ea1->reg) {
  1582.     case CRP:
  1583.     case SRP:
  1584.     case DRP:
  1585.         if (ea2->type == DN)
  1586.         Gen68Error("Reg. size mismatch");
  1587.         break;
  1588.     }
  1589.     eword(op + Ppid + modreg(ea2));
  1590.     eword(op2 + ea1->reg);
  1591.     finish(ea2);
  1592.     break;
  1593.  
  1594.     case PSCC:            /* PMMU set on condition (also pflushr) */
  1595.     eword(op + Ppid + modreg(ea1));
  1596.     eword(op2);
  1597.     finish(ea1);
  1598.     break;
  1599.  
  1600.     case PTEST:        /* PMMU test logical address */
  1601.     eword(op + Ppid + modreg(ea2));
  1602.     if (ea4->type == AN)
  1603.         op2 += (ea4->reg + 8) << 5;
  1604.     eword(op2 + (check(ea3->konst, LOW3) << 10) + pmmu_fc(ea1));
  1605.     finish(ea2);
  1606.     break;
  1607.  
  1608.     case PTRAPCC:        /* PMMU trap on condition */
  1609.     eword(op + Ppid + (thesz == W ? 2 : 3));
  1610.     eword(op2);
  1611.     if (thesz == L)
  1612.         elong(ea1->konst);
  1613.     else
  1614.         eword(check(ea1->konst, UWORD));
  1615.     break;
  1616.  
  1617.     case PVALID:        /* PMMU validate a pointer */
  1618.     eword(op + Ppid +ªdà`ea2));
  1619.     if (ea1->type == AN)
  1620.         eword(op2 + ea1->reg);
  1621.     else
  1622.         eword(op2);
  1623.     finish(ea2);
  1624.     break;
  1625. #endif
  1626.  
  1627. #ifdef COPROC
  1628.     case CPINH:        /* co-processor inherent */
  1629.     eword(op + cpid(ea1->konst));
  1630.     eword(check(ea2->konst, LOW6));
  1631.     break;
  1632.  
  1633.     case CPBCC:        /* co-processor branch on condition */
  1634.     eword(op + cpid(ea1->konst)
  1635.           + (thesz == L ? 0x40 : 0)
  1636.           + check(ea2->konst, LOW6));
  1637.     dist = ea3->konst - Pc;
  1638.     if (thesz == L)
  1639.         elong(dist);
  1640.     else
  1641.         eword(check(dist, SWORD));
  1642.     break;
  1643.  
  1644.     case CPDBCC:        /* co-processor dec & branch */
  1645.     eword(op + cpid(ea1->konst) + ea2->reg);
  1646.     eword(check(ea2->konst, LOW6));
  1647.     dist = ea3->konst - Pc;
  1648.     eword(check(dist, SWORD));
  1649.     break;
  1650.  
  1651.     case CPGEN:        /* co-processor generic */
  1652.     eword(op + cpid(ea1->konst) + modreg(ea3));
  1653.     eword(ea2->konst);
  1654.     finish(ea3);
  1655.     break;
  1656.  
  1657.     case CPEA:            /* co-processor, 1 ea (save/restore) */
  1658.     eword(op + cpid(ea1->konst) + modreg(ea2));
  1659.     finish(ea2);
  1660.     break;
  1661.  
  1662.     case CPSCC:        /* co-processor set on condition */
  1663.     eword(op + cpid(ea1->konst) + modreg(ea3));
  1664.     eword(check(ea2->konst, LOW6));
  1665.     finish(ea3);
  1666.     break;
  1667.  
  1668.     case CPTRAPCC:        /* co-processor trap on condition */
  1669.     eword(op + cpid(ea1->konst) + (thesz == W ? 2 : 3));
  1670.     eword(check(ea2->konst, LOW6));
  1671.     if (thesz == L)
  1672.         elong(ea3->konst);
  1673.     else
  1674.         eword(check(ea3->konst, UWORD));
  1675.     break;
  1676. #endif
  1677.  
  1678.     case CODEW:        /* Used for outputting traps in code */
  1679.     eword(ea1->konst);
  1680.     break;
  1681.  
  1682.     default:
  1683.     Gen68Error("Error in Mnemonic table");
  1684.     }
  1685. }
  1686.  
  1687. char                           *stypes[] =
  1688. {"Symbol: ", "Status:  ", "Data:   ", "Address: ", "Control: ",
  1689.  "Float:  ", "Fcontrol:", "PCrel:  ", "ZPCrel:  ", "ZAddress:",
  1690.  "ZData:  ", "Pmmu:    "};
  1691.  
  1692. #ifdef PMMU
  1693. /*
  1694.  * pmmu_fc --- return encoding for function code specifier
  1695.  */
  1696. int
  1697. pmmu_fc(struct ea * e)
  1698. {
  1699.     int                             fc;
  1700.  
  1701.     if (e->type == EXPR)
  1702.     fc = 0x10 + check(e->konst, LOW4);
  1703.     else if (e->type == DN)
  1704.     fc = 0x8 + e->reg;
  1705.     else if (e->type == CN && e->reg == SFC)
  1706.     fc = 0;
  1707.     else if (e->type == CN && e->reg ,D†== DFC)
  1708.     fc = 1;
  1709.     else
  1710.     Gen68Error("Bad Func. Code specifier");
  1711.     return (fc);
  1712. }
  1713.  
  1714. #endif
  1715.  
  1716.  
  1717. /*
  1718.  * process --- determine mnemonic class and act on it
  1719.  */
  1720. void
  1721. process(InstVia_t inst)
  1722. {
  1723.     register struct mne            *m;
  1724.     register struct tmpl           *t;
  1725.     struct mne                     *mne_lookOP();
  1726.     struct tmpl                    *tmpl_match();
  1727.  
  1728.     Old_pc = Pc;        /* setup `old' program counter */
  1729.     switch (Via(inst)->SZ) {
  1730.     case M68sz_byte:
  1731.     thesz = B;
  1732.     break;
  1733.     case M68sz_word:
  1734.     thesz = W;
  1735.     break;
  1736.     case M68sz_long:
  1737.     thesz = L;
  1738.     break;
  1739.     case M68sz_none:
  1740.     thesz = U;
  1741.     break;
  1742.     case M68sz_single:
  1743.     thesz = S;
  1744.     break;
  1745.     case M68sz_double:
  1746.     thesz = D;
  1747.     break;
  1748.     case M68sz_extended:
  1749.     thesz = U;
  1750.     break;
  1751.     default:
  1752.     thesz = U;
  1753.     break;
  1754.     }
  1755.  
  1756.     assert(Pass == 2 ? Via(inst)->Address == Pc : 1);
  1757.     Via(inst)->Address = Pc;
  1758.     if (Via(inst)->OP == M68op_DELETED) {
  1759.         return;
  1760.     }
  1761.     m = mne_lookOP(Via(inst)->OP);
  1762.     if (m) {
  1763. #ifdef OLDMEM
  1764.     HLock((Handle) inst);
  1765. #endif
  1766.     BitsBuffer = Via(inst)->Bytes;
  1767.     BBIndex = 0;
  1768.     t = tmpl_match(m->ptmpl, m->ntmpl, inst);
  1769.     if (t) {
  1770.         do_op(t->opclass, t->op, t->op2);
  1771.         assert(Pass == 2 ? Via(inst)->InstSize == BBIndex : 1);
  1772.         Via(inst)->InstSize = BBIndex;
  1773.     } else {
  1774.         Gen68Error("Operand mismatch");
  1775.     }
  1776. #ifdef OLDMEM
  1777.     HUnlock((Handle) inst);
  1778. #endif
  1779.     }
  1780. }
  1781.